package api

import (
	"encoding/json"
	"errors"
	"fmt"
	tp "gitee.com/swsk33/concurrent-task-pool/v2"
	"gitee.com/swsk33/landsat-fetch/global"
	"gitee.com/swsk33/landsat-fetch/model"
	"gitee.com/swsk33/sclog"
	"runtime"
)

// GetDownloadList 获取全部下载列表
func GetDownloadList() ([]string, error) {
	// 发送请求
	response, e := global.SendRequest("/download-labels", "POST", []byte("{\"downloadApplication\":\"BulkDownload\"}"))
	if e != nil {
		sclog.ErrorLine("发送查询请求失败！")
		return nil, e
	}
	// 反序列化
	var result model.BasicResponse[[]model.DownloadListData]
	e = json.Unmarshal(response, &result)
	if e != nil {
		sclog.ErrorLine("反序列化查询响应失败！")
		return nil, e
	}
	// 返回结果
	list := make([]string, 0)
	for _, item := range result.Data {
		list = append(list, item.Label)
	}
	return list, nil
}

// LoadDownloadList 加载下载列表
// 只有加载下载列表后，才能获取下载链接
//
// label 要加载的影像下载列表名
//
// 返回下载任务id列表
func LoadDownloadList(label string) ([]int64, error) {
	// 发送请求
	response, e := global.SendRequest("/download-order-load", "POST", []byte(fmt.Sprintf("{\"label\":[\"%s\"],\"downloadApplication\":\"BulkDownload\"}", label)))
	if e != nil {
		sclog.ErrorLine("发送加载下载列表请求失败！")
		return nil, e
	}
	// 反序列化响应
	var result model.BasicResponse[[]model.LoadListData]
	e = json.Unmarshal(response, &result)
	if e != nil {
		sclog.ErrorLine("反序列化响应失败！")
		return nil, e
	}
	if result.Data == nil {
		return nil, errors.New("加载下载列表失败！")
	}
	list := make([]int64, 0)
	for _, item := range result.Data {
		list = append(list, item.DownloadId)
	}
	return list, nil
}

// GetDownloadUrlList 获取下载链接
//
// label 列表名称
func GetDownloadUrlList(label string) ([]*model.GranuleTask, error) {
	// 发送请求
	response, e := global.SendRequest("/download-retrieve", "POST", []byte(fmt.Sprintf("{\"label\":\"%s\",\"downloadApplication\":\"BulkDownload\"}", label)))
	if e != nil {
		sclog.ErrorLine("发送获取下载链接请求失败！")
		return nil, e
	}
	// 反序列化
	var result model.BasicResponse[model.RetrieveListData]
	e = json.Unmarshal(response, &result)
	if e != nil {
		sclog.ErrorLine("反序列化下载链接请求响应失败！")
		return nil, e
	}
	// 提取结果
	resultMap := make(map[string]*model.RetrieveDownloadData)
	for _, item := range result.Data.Available {
		resultMap[item.DisplayId] = &item
	}
	for _, item := range result.Data.Requested {
		resultMap[item.DisplayId] = &item
	}
	// 存入结果
	list := make([]*model.GranuleTask, 0, len(resultMap))
	for _, item := range resultMap {
		list = append(list, model.NewGranuleTask(item.DisplayId, item.Url, item.Label))
	}
	return list, nil
}

// DeleteDownloadList 删除下载列表
//
// label 删除的列表标签名
func DeleteDownloadList(label string) error {
	// 首先请求全部列表
	sclog.InfoLine("正在查询任务列表...")
	list, e := LoadDownloadList(label)
	if e != nil {
		return e
	}
	// 逐一删除
	// 使用并发任务池删除
	sclog.InfoLine("开始移除任务...")
	pool := tp.NewSimpleTaskPool[int64](runtime.NumCPU(), list,
		func(id int64, pool *tp.TaskPool[int64]) {
			response, e := global.SendRequest("/download-remove", "POST", []byte(fmt.Sprintf("{\"downloadId\":\"%d\"}", id)))
			if e != nil {
				sclog.BufferError("发送删除任务请求失败！id：%d原因：%s\n", id, e)
				sclog.BufferWarnLine("将会后续重试删除...")
				pool.Retry(id)
				return
			}
			var result model.BasicResponse[bool]
			e = json.Unmarshal(response, &result)
			if e != nil {
				sclog.BufferError("反序列化删除任务请求响应失败！id：%d原因：%s\n", id, e)
				sclog.BufferWarnLine("将会后续重试删除...")
				pool.Retry(id)
				return
			}
			if !result.Data {
				sclog.BufferError("删除任务：%d失败！原因：%s\n", id, result.ErrorMessage)
				sclog.BufferWarnLine("将会后续重试删除...")
				pool.Retry(id)
				return
			}
			sclog.BufferInfo("已删除任务，id：%d\n", id)
		})
	pool.Start()
	return nil
}